package com.example.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.mapper.IdempotentMapper;
import com.example.po.IdempotentPO;
import com.example.service.IdempotentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;

/*
@description:
@ClassName IdempotentServiceImpl
@author chen
@create 2025-07-09 22:32
@Version 1.0
*/
@Service
public class IdempotentServiceImpl implements IdempotentService
{
    @Resource
    private IdempotentMapper idempotentMapper;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Override
    public int idempotent(String idempotentKey, Runnable r)
    {
        // 根据 idempotentKey 查找记录，如果能找到，说明业务已成功处理过
        IdempotentPO idempotentPO = this.getByIdempotentKey(idempotentKey);
        if (idempotentPO != null)
        {
            return -1;
        }
        transactionTemplate.executeWithoutResult(action ->
        {
            // 执行业务
            r.run();
            // 如果这个地方有并发，则由于（t_idempotent.idempotent_key）的唯一性，会导致有一个会执行失败，抛出异常，导致事务回滚
            IdempotentPO po = new IdempotentPO();
            po.setId(IdUtil.fastSimpleUUID());
            po.setIdempotentKey(idempotentKey);
            this.idempotentMapper.insert(po);
        });
        return 1;
    }


    private IdempotentPO getByIdempotentKey(String idempotentKey)
    {
        LambdaQueryWrapper<IdempotentPO> qw =
                Wrappers.lambdaQuery(IdempotentPO.class)
                        .eq(IdempotentPO::getIdempotentKey, idempotentKey);
        return this.idempotentMapper.selectOne(qw);
    }
}
